﻿using System;
//using System.Linq;
using System.Runtime.InteropServices;
using System.ComponentModel;
//using System.Collections.Generic;

namespace SmartWeighMonitor
{
    /// Datastead RTSP/RTMP DirectShow source filter.
    public class RTSPFilter
    {
        public const string FilterName = "Datastead RTSP/RTMP/HTTP/ONVIF DirectShow Source Filter";
        // values to pass to SetInt (RTSP_Source_RTSPTransport_int, value)
        public const int RTSPTransportMode_Auto = 0;
        public const int RTSPTransportMode_TCP = 1;
        public const int RTSPTransportMode_UDP = 2;
        public const int RTSPTransportMode_HTTP = 3;
        public const int RTSPTransportMode_Udp_Multicast = 4;


        const int EC_USER = 0x8000; // from DirectShow, comment this line if you get an "already defined" error
        public const int EC_RTSPNOTIFY = EC_USER + 0x4000;
        public const int EC_RTSP_PARAM1_DISKFULL = 1;
        public const int EC_RTSP_PARAM1_DEVICELOST_RECONNECTING = 3;
        public const int EC_RTSP_PARAM1_DEVICELOST_RECONNECTED = 4;
        public const int EC_RTSP_PARAM1_RECORDTONEWFILE_COMPLETED = 5;
        public const int EC_RTSP_PARAM1_OPENURLASYNC_CONNECTION_RESULT = 6;
        public const int EC_RTSP_PARAM1_FRAME_CAPTURE_SUCCEEDED = 7;
        public const int EC_RTSP_PARAM1_FRAME_CAPTURE_FAILED = 8;
        public const int EC_RTSP_PARAM1_ONVIF_SNAPSHOT_SUCCEEDED = 9;
        public const int EC_RTSP_PARAM1_ONVIF_SNAPSHOT_FAILED = 10;

        public static readonly Guid DatasteadRtspFilterCLSID = new Guid("55D1139D-5E0D-4123-9AED-575D7B039569");

        public static readonly Guid DatasteadVideoRendererCLSID = new Guid("C7CC1A23-8B8A-4BFD-A96C-B5E735E055BA");

        // IDatasteadRTSPSourceConfig
        [ComImport, Guid("D7557B82-3FA4-4F4F-B7CF-96108202E4AF"), System.Security.SuppressUnmanagedCodeSecurity, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IDatasteadRTSPSourceConfig
        {
            [PreserveSig] int GetBool([In, MarshalAs(UnmanagedType.LPWStr)] string ParamID, [Out] out bool Value);
            [PreserveSig] int GetDouble([In, MarshalAs(UnmanagedType.LPWStr)] string ParamID, [Out] out double Value);
            [PreserveSig] int GetInt([In, MarshalAs(UnmanagedType.LPWStr)] string ParamID, [Out] out int Value);
            [PreserveSig] int GetStr([In, MarshalAs(UnmanagedType.LPWStr)] string ParamID, [Out] out IntPtr Value);
            [PreserveSig] int SetBool([In, MarshalAs(UnmanagedType.LPWStr)] string ParamID, [In] bool Value);
            [PreserveSig] int SetDouble([In, MarshalAs(UnmanagedType.LPWStr)] string ParamID, [In] double Value);
            [PreserveSig] int SetInt([In, MarshalAs(UnmanagedType.LPWStr)] string ParamID, [In] int Value);
            [PreserveSig] int SetStr([In, MarshalAs(UnmanagedType.LPWStr)] string ParamID, [In, MarshalAs(UnmanagedType.LPWStr)] string Value);
            [PreserveSig] int Action([In, MarshalAs(UnmanagedType.LPWStr)] string ActionID, [In, MarshalAs(UnmanagedType.LPWStr)] string Option);
        }

        // IDatasteadRTSPSourceConfig2 : IDatasteadRTSPSourceConfig
        [ComImport, Guid("932C369A-3335-45BB-B5F4-A6CF77F9B40C"), System.Security.SuppressUnmanagedCodeSecurity, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IDatasteadRTSPSourceConfig2 : IDatasteadRTSPSourceConfig
        {
            [PreserveSig] int GetIntPtr([In, MarshalAs(UnmanagedType.LPWStr)] string ParamID, [Out] out IntPtr Value);
        }

        // IDatasteadRTSPSourceConfig3 : IDatasteadRTSPSourceConfig2
        [ComImport, Guid("6FCA28BE-7F96-467A-BB08-0611FC8162B7"), System.Security.SuppressUnmanagedCodeSecurity, InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IDatasteadRTSPSourceConfig3 : IDatasteadRTSPSourceConfig2
        {
            [PreserveSig] int GetInt64([In, MarshalAs(UnmanagedType.LPWStr)] string ParamID, [Out] out Int64 Value);
            [PreserveSig] int SetInt64([In, MarshalAs(UnmanagedType.LPWStr)] string ParamID, [In] Int64 Value);
        }
        //_________________________________________________________________________________
        // Current state: returned by DatasteadRTSPSourceConfig.GetInt (RTSP_Source_GetState_int, out SourceState)
        //_________________________________________________________________________________

        public enum TSourceState { state_disconnected, state_connecting_async, state_connecting_sync, state_reconnecting, state_connected, state_previewing, state_recording_paused, state_recording_active };

        //_________________________________________________________________________________
        // Filter configuration identifiers that are supported as ParamID by the IDatasteadRTSPSourceConfig functions
        //_________________________________________________________________________________
        public enum RTSPConfigParam
        {
            RTSP_Action_OpenURL,
            RTSP_Action_OpenURLAsync,
            RTSP_Action_GetONVIFSnapshot,
            RTSP_Action_GetONVIFSnapshotAsync,
            RTSP_Action_RecordToNewFileNow,
            RTSP_Action_CancelPendingConnection,
            RTSP_Action_PauseURL,
            RTSP_Action_ResumeURL,
            RTSP_Action_PauseRecording,
            RTSP_Action_ResumeRecording,
            RTSP_Action_CaptureFrame,
            RTSP_Action_UpdateDuration,

            RTSP_Source_RecordingFileName_str,
            RTSP_Source_RecordingBacktimedStartSeconds_int,
            RTSP_Source_Recording_Title_str,
            RTSP_Source_PlayableWhileRecording_int,
            RTSP_Source_ContinuousRecording_bool,
            RTSP_Source_MaxAnalyzeDuration_int,
            RTSP_Source_AutoReconnect_bool,
            RTSP_Source_NoTranscoding_bool,
            RTSP_Source_DeviceLostTimeOut_int,
            RTSP_Source_BufferDuration_int,
            RTSP_Source_LowDelay_int,
            RTSP_Source_SampleDeliveryMode_int,
            RTSP_Source_ConnectionTimeOut_int,
            RTSP_Source_RTSPTransport_int,
            RTSP_Source_RTSPRange_str,
            RTSP_Source_Format_str,
            RTSP_Source_FrameRate_double,
            RTSP_Source_AverageTimePerFrame100ns_int,
            RTSP_Source_DurationMs_int,
            RTSP_Source_Duration100ns_int64,
            RTSP_Source_VideoSize_str,
            RTSP_Source_VideoCodec_str,
            RTSP_Source_AuthUser_str,
            RTSP_Source_AuthPassword_str,
            RTSP_Source_StreamInfo_str,
            RTSP_Source_StartTime_int,
            RTSP_Source_Threads_int,
            RTSP_Source_IsURLConnected_bool,
            RTSP_Source_GetAudioDevices_str,
            RTSP_Source_SetAudioDevice_str,
            RTSP_Source_GetURL_str,
            RTSP_Source_GetState_int,

            RTSP_ONVIF_LastJPEGSnapshotBuffer_intptr,
            RTSP_ONVIF_LastJPEGSnapshotSize_int,

            RTSP_VideoStream_Enabled_bool,
            RTSP_VideoStream_Synchronized_bool,
            RTSP_VideoStream_Recorded_bool,
            RTSP_VideoStream_Index_int,
            RTSP_VideoStream_PinFormat_str,
            RTSP_VideoStream_Width_int,
            RTSP_VideoStream_Height_int,
            RTSP_VideoStream_AspectRatio_double,
            RTSP_VideoStream_TopDown_bool,
            RTSP_VideoStream_FrameRateMax_double,
            RTSP_VideoStream_Filter_str,
            RTSP_VideoStream_HWAcceleration_int,
            RTSP_VideoStream_Deinterlacing_int,
            RTSP_VideoStream_ConfigureTextOverlay_str,
            RTSP_VideoStream_ConfigureHueBrightSat_str,
            RTSP_VideoStream_DelayMs_int,

            RTSP_AudioStream_Enabled_bool,
            RTSP_AudioStream_Recorded_bool,
            RTSP_AudioStream_Index_int,
            RTSP_AudioStream_Filter_str,
            RTSP_AudioStream_Volume_int,
            RTSP_AudioStream_DelayMs_int,

            RTSP_FrameCapture_Width_int,
            RTSP_FrameCapture_Height_int,
            RTSP_FrameCapture_Time_int,
            RTSP_FrameCapture_FileName_str,

            RTSP_CurrentRecording_FileSizeKb_int,
            RTSP_CurrentRecording_ClipDurationMs_int,
            RTSP_CurrentRecording_VideoFrameCount_int,
            RTSP_CurrentRecording_FileName_str,

            RTSP_LastRecorded_FileSizeKb_int,
            RTSP_LastRecorded_ClipDurationMs_int,
            RTSP_LastRecorded_VideoFrameCount_int,
            RTSP_LastRecorded_FileName_str,

            RTSP_Dest_URL_str,
            RTSP_Dest_Video_BitRate_int,
            RTSP_Dest_Video_Quality_int,
            RTSP_Dest_Video_KeyFrameInterval_int,

            RTSP_Filter_Version_int,
            RTSP_Filter_Build_int,
            RTSP_Filter_LicenseKey_str
        };

        public delegate void OpenURLAsyncCompletionCB(IntPtr Sender, IntPtr CustomParam, UInt32 Result);

        [ComImport,
            Guid("58D66E77-B19C-4F9A-8B47-DFE1CA87B642"),
            System.Security.SuppressUnmanagedCodeSecurity,
            InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IDatasteadRTSPSourceCallbackConfig
        {
            [PreserveSig] int SetAsyncOpenURLCallback(OpenURLAsyncCompletionCB CallbackFunctionPtr, IntPtr Sender, IntPtr CustomParam);
        }

        /** <summary> 
        <para>type of the sample callback function</para>
        */
        [UnmanagedFunctionPointer(CallingConvention.StdCall)]
        public delegate void DatasteadRTSP_RawSampleCallback(IntPtr Sender, Int32 StreamNumber, IntPtr CodecName, Int64 SampleTime_Absolute, Int64 SampleTime_Relative, IntPtr Buffer, Int32 BufferSize, IntPtr InfoString);
        public delegate void DatasteadRTSP_VideoSampleCallback(IntPtr Sender, Int64 SampleTime_Absolute, Int64 SampleTime_Relative, IntPtr Buffer, Int32 BufferSize, Int32 VideoWidth, Int32 VideoHeight, Int32 BitCount, Int32 Stride);
        public delegate void DatasteadRTSP_AudioSampleCallback(IntPtr Sender, Int64 SampleTime_Absolute, Int64 SampleTime_Relative, IntPtr Buffer, Int32 BufferSize, Int32 SamplesPerSec, Int32 Channels, Int32 BitsPerSample);

        /** <summary> 
        <para>uncompressed audio and video sample callbacks</para>
        <para>Makes and return a copy of each sample uncompressed</para>
        */
        [ComImport,
            Guid("799485B3-0DA1-4F74-90E2-5684C9CD949B"),
            System.Security.SuppressUnmanagedCodeSecurity,
            InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IDatasteadRTSPSampleCallback
        {
            /** <summary> 
            <para>this function is used to configure the callback that occurs after invoking Action (RTSP_Action_OpenURLAsync, ...) when the URL opening completes. Parameters:</para>
            <para>DatasteadRTSPSampleCallback: address of your callback function</para>
            <para>Sender: pass a pointer to the current instance of your class, it will be returned as parameter when the callback occurs</para>
            */
            [PreserveSig]
            int SetRawSampleCallback(IntPtr SampleCallback, IntPtr Sender);
            int SetVideoRGBSampleCallback(IntPtr SampleCallback, IntPtr Sender);
            int SetAudioPCMSampleCallback(IntPtr SampleCallback, IntPtr Sender);
        }

        /** <summary> 
        <para>direct access to the uncompressed RGB video sample before it is delivered to the output pin</para>
        <para>From this callback you can modify the video sample (e.g. apply an overlay) before it is delived</para>
        */
        [ComImport,
            Guid("845F8BAF-A774-4C46-A17A-F037613B9FC2"),
            System.Security.SuppressUnmanagedCodeSecurity,
            InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
        public interface IDatasteadRTSPSampleCallback2
        {
            /** <summary> 
            <para>this function is used to configure the callback that occurs after invoking Action (RTSP_Action_OpenURLAsync, ...) when the URL opening completes. Parameters:</para>
            <para>DatasteadRTSPSampleCallback: address of your callback function</para>
            <para>Sender: pass a pointer to the current instance of your class, it will be returned as parameter when the callback occurs</para>
            */
            [PreserveSig]
            int SetVideoRGBOverlayCallback(IntPtr SampleCallback, IntPtr Sender);
        }

    }
}
